﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Vertica.Data.VerticaClient;
using Vertica.Data;
using System.Data;
using System.IO;
using Hp.Vertica.Client.Internal;

namespace Hp.Vertica.Client.Internal
{
    public class VerticaContext
    {
//        public VerticaContext()
//        {
//        }
//        public VerticaContext(String host, String user, String password, String database)
//        {
//            this.Host = host;
//            this.User = user;
//            this.Password = password;
//            this.Database = database;
//        }

//        public String Host { get; set; }
//        public String User { get; set; }
//        public String Password { get; set; }
//        public String Database { get; set; }

//        public List<Schema> Schemas
//        {
//            get
//            {
//                return null;
//            }
//        }

//        public void Create(Table target)
//        {
//            this.execute(target.ToString());
//        }

//        public void Import(DataTable data, Table target)
//        {
//            if (target.Identity != null)
//            {
//                this.ImportIdentity(data, target);
//                return;
//            }
//            using (VerticaConnection conn = new VerticaConnection(this.ConnectionString))
//            {
//                conn.Open();
//                var cmd = conn.CreateCommand();
//                //insert data
//                cmd.CommandText = target.GetInsertScript();
//                foreach (VerticaColumn col in target.Columns)
//                {
//                    cmd.Parameters.Add(new VerticaParameter(col.Name, ((VerticaDataType)col.DataType).VerticaType));
//                }
//                foreach (DataRow dr in data.Rows)
//                {
//                    foreach (VerticaColumn col in target.Columns)
//                    {
//                        cmd.Parameters[col.Name].Value = dr[col.Name];
//                    }
//                    cmd.ExecuteNonQuery();
//                }
//                conn.Close();
//            }
//        }

//        private void ImportIdentity(DataTable data, Table target)
//        {
//            Boolean hasIdentity = (target.Identity != null);
//            String identityCol = target.Identity.Name;
//            Int64 identity = 1;
//            List<Int64> fakeIds = new List<Int64>();

//            using (VerticaConnection conn = new VerticaConnection(this.ConnectionString))
//            {
//                conn.Open();
//                var cmd = conn.CreateCommand();
//                //insert data
//                cmd.CommandText = target.GetInsertScript();
//                foreach (VerticaColumn col in target.Columns.Where(c => !c.IsIdentity))
//                {
//                    cmd.Parameters.Add(new VerticaParameter(col.Name, ((VerticaDataType)col.DataType).VerticaType));
//                }
//                foreach (DataRow dr in data.Rows)
//                {
//                    foreach (VerticaColumn col in target.Columns.Where(c => !c.IsIdentity))
//                    {
//                        cmd.Parameters[col.Name].Value = dr[col.Name];
//                    }
//                    Int64 currentId = Int64.Parse(dr[identityCol].ToString());
//                    while (identity <= currentId)
//                    {
//                        cmd.ExecuteNonQuery();
//                        if (identity < currentId)
//                        {
//                            fakeIds.Add(identity);
//                        }
//                        identity++;
//                    }
//                }
//                //delete fake data
//                cmd.Parameters.Clear();
//                cmd.CommandText = target.GetDeleteScript(identityCol);
//                cmd.Parameters.Add(new VerticaParameter(identityCol, VerticaType.BigInt));
//                foreach (var id in fakeIds)
//                {
//                    cmd.Parameters[identityCol].Value = id;
//                    cmd.ExecuteNonQuery();
//                }
//                conn.Close();
//            }
//        }

//        private void execute(String query)
//        {
//            using (VerticaConnection conn = new VerticaConnection(this.ConnectionString))
//            {
//                conn.Open();
//                var cmd = conn.CreateCommand();
//                cmd.CommandText = query;
//                cmd.ExecuteNonQuery();
//                conn.Close();
//            }
//        }

//        protected string ConnectionString
//        {
//            get
//            {
//                VerticaConnectionStringBuilder sb = new VerticaConnectionStringBuilder();
//                sb.Host = this.Host;
//                sb.Database = this.Database;
//                sb.User = this.User;
//                sb.Password = this.Password;

//                return sb.ToString();
//            }
//        }

//        public Boolean TableExist(string schemaName, string tableName)
//        {
//            using (VerticaConnection conn = new VerticaConnection(this.ConnectionString))
//            {
//                conn.Open();
//                var cmd = conn.CreateCommand();
//                cmd.CommandText = @"SELECT COUNT(0)
//                                    FROM v_catalog.tables
//                                    WHERE table_schema = @schemaName
//                                    AND table_name = @tableName;";
//                cmd.Parameters.Add(new VerticaParameter("schemaName", schemaName));
//                cmd.Parameters.Add(new VerticaParameter("tableName", tableName));
//                Int32 result = Int32.Parse(cmd.ExecuteScalar().ToString());
//                return (result == 1);
//            }
//        }

//        public Table GetTable(string schemaName, string tableName)
//        {
//            Table tb = new Table();
//            tb.Schema = schemaName;
//            tb.Name = tableName;
//            using (VerticaConnection conn = new VerticaConnection(this.ConnectionString))
//            {
//                conn.Open();
//                var cmd = conn.CreateCommand();
//                cmd.CommandText = @"SELECT c.column_name
//                                    , t.type_name
//                                    , ISNULL(c.character_maximum_length, 0) AS max_length
//                                    , ISNULL(c.numeric_precision, isnull(c.datetime_precision, 0)) AS precision
//                                    , ISNULL(c.numeric_scale, 0) AS scale
//                                    , c.is_nullable
//                                    , c.is_identity
//                                    FROM v_catalog.columns c
//                                    JOIN v_catalog.types t
//                                    ON c.data_type_id = t.type_id
//                                    WHERE table_schema = @schemaName
//                                    AND table_name = @tableName
//                                    ORDER BY ordinal_position;";
//                using (VerticaDataReader dr = cmd.ExecuteReader())
//                {
//                    while (dr.Read())
//                    {
//                        VerticaColumn col = new VerticaColumn();
//                        col.Name = dr["column_name"].ToString();
//                        col.IsIdentity = Boolean.Parse(dr["is_identity"].ToString());
//                        col.IsNullable = Boolean.Parse(dr["is_nullable"].ToString());
//                        var size = Int32.Parse(dr["max_length"].ToString());
//                        var precision = Int32.Parse(dr["precision"].ToString());
//                        var scale = Int32.Parse(dr["scale"].ToString());
//                        //col.DataType = DataTypeFactory.CreateSqlDataType(dr["type_name"].ToString(), size, precision, scale);
//                        tb.AddColumn(col);
//                    }
//                }
//            }

//            return tb;
//        }

//        public long BulkLoad(DataTable data, Table target)
//        {
//            StringBuilder sb = new StringBuilder();
//            foreach (DataRow row in data.Rows)
//            {
//                int colIndex = 0;
//                foreach (DataColumn column in data.Columns)
//                {
//                    if (colIndex > 0)
//                    {
//                        sb.Append(Table.ColumnDelimiter);
//                    }
//                    sb.Append(row.IsNull(column) ? String.Empty : row[column].ToString());
//                    colIndex++;
//                }
//                sb.Append(Table.RowTerminator);
//            }
//            byte[] buff = Encoding.Default.GetBytes(sb.ToString());
//            using (MemoryStream stream = new MemoryStream(buff, 0, buff.Length))
//            {
//                stream.Flush();
//                stream.Position = 0;

//                using (VerticaConnection conn = new VerticaConnection(this.ConnectionString))
//                {
//                    conn.Open();
//                    VerticaCopyStream cp = new VerticaCopyStream(conn, target.BulkCopyScript);
//                    cp.Start();
//                    cp.AddStream(stream, false);
//                    cp.Execute();
//                    conn.Close();
//                    return cp.RowCount;
//                }
//            }
//        }
    }
}
